const User = require('../models/userModel');
const tokenUtils = require('../utils/tokenUtils');

// 用户注册服务
exports.registerUser = async (userData) => {
    // 检查用户名或邮箱是否已存在
    const existingUser = await User.findOne({
        $or: [
            { username: userData.username },
            { email: userData.email }
        ]
    });

    if (existingUser) {
        if (existingUser.username === userData.username) {
            throw { status: 409, message: '用户名已存在' };
        } else {
            throw { status: 409, message: '邮箱已被注册' };
        }
    }

    // 创建新用户
    const newUser = new User(userData);
    await newUser.save();

    // 生成访问令牌
    const token = tokenUtils.generateAccessToken(newUser._id);

    return {
        userId: newUser._id,
        token
    };
};

// 用户登录服务
exports.loginUser = async (credentials) => {
    // 查找用户
    const user = await User.findOne({ username: credentials.username });
    if (!user) {
        throw { status: 401, message: '用户名或密码错误' };
    }

    // 验证密码
    const isPasswordValid = await user.comparePassword(credentials.password);
    if (!isPasswordValid) {
        throw { status: 401, message: '用户名或密码错误' };
    }

    // 生成令牌
    const token = tokenUtils.generateAccessToken(user._id);
    const refreshToken = tokenUtils.generateRefreshToken(user._id);

    // 保存刷新令牌到用户记录
    user.refreshToken = refreshToken;
    await user.save();

    return {
        token,
        refreshToken
    };
};

// 刷新令牌服务
exports.refreshToken = async (oldToken, refreshToken) => {
    if (!oldToken || !refreshToken) {
        throw { status: 401, message: '缺少令牌' };
    }

    // 验证刷新令牌
    const refreshPayload = tokenUtils.verifyToken(refreshToken);
    if (!refreshPayload) {
        throw { status: 401, message: '刷新令牌无效或已过期' };
    }

    // 查找用户并验证刷新令牌
    const user = await User.findById(refreshPayload.userId);
    if (!user || user.refreshToken !== refreshToken) {
        throw { status: 401, message: '刷新令牌已失效' };
    }

    // 生成新的访问令牌
    const newToken = tokenUtils.generateAccessToken(user._id);

    return {
        token: newToken
    };
}; 